package com.godtree.util;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Tuple;
import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Lists;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.LinkedList;

/**
 * @author lisicheng
 * @date 2022-08-09
 */
public class UnitConvertUtil {

  private static final BigDecimal ONE_HUNDRED_MILLION = BigDecimal.valueOf(100000000);

  private static final BigDecimal TEN_THOUSAND = BigDecimal.valueOf(10000);

  private static final String EMPTY_STR = StrUtil.EMPTY;

  private final String unitConvert;

  public UnitConvertUtil(String unitConvert) {
    this.unitConvert = unitConvert;
  }

  /**
   * 10000000000000000 = 1亿亿
   * <p/>
   * 100000000000000 = 100万亿
   * <p/>
   * 1000000000000 = 1万亿
   * <p/>
   * 100000000 = 1亿
   * <p/>
   * 10000000 = 1000万
   * <p/>
   * 1000000 = 100万
   * <p/>
   * 100000 = 10万
   * <p/>
   * 10000 = 1万
   * <p/>
   * 1000 = 1000
   * <p/>
   * 100 = 100
   *
   * @param num 数字
   * @return Tuple<BigDecimal, BigDecimal, String> before, after, unit
   */
  public Tuple convert(BigDecimal num) {

    if (num == null || num.compareTo(BigDecimal.ZERO) == 0) {
      return empty(BigDecimal.ZERO);
    }

    BigDecimal result = num;
    LinkedList<String> linkedList = Lists.newLinkedList();
    while (true) {
      if (num.compareTo(ONE_HUNDRED_MILLION) >= 0) {
        num = num.divide(ONE_HUNDRED_MILLION, 2, RoundingMode.DOWN);
        linkedList.add("亿");
      } else if (num.compareTo(TEN_THOUSAND) >= 0) {
        num = num.divide(TEN_THOUSAND, 2, RoundingMode.DOWN);
        linkedList.add("万");
      } else {
        return of(result, num, StrUtil.join("", ListUtil.reverse(linkedList)));
      }
    }
  }

  public Tuple empty(BigDecimal num) {
    return of(num, num, EMPTY_STR);
  }

  private Tuple of(BigDecimal before, BigDecimal after, String unit) {
    boolean unitConvert = "1".equals(this.unitConvert);
    // 去除小数点后面的0
    before = before == null ? null : new BigDecimal(before.stripTrailingZeros().toPlainString());
    after = after == null ? null : new BigDecimal(after.stripTrailingZeros().toPlainString());
    return new Tuple(before, unitConvert ? after : before, unitConvert ? unit : EMPTY_STR);
  }

}
